package springbootelasticsearchrepository.springbootelasticsearchrepository.controller;


import com.google.gson.Gson;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.QueryStringQueryBuilder;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springbootelasticsearchrepository.springbootelasticsearchrepository.dao.EmployeeRepository;
import springbootelasticsearchrepository.springbootelasticsearchrepository.pojo.Employee;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("es")
public class EmployeeController {

    @Autowired
    private EmployeeRepository employeeRepository;

    /**
     * 添加
     *
     * @return
     */
    @RequestMapping("add")
    public String add() {
        Employee employee = new Employee();
        employee.setId("3");
        employee.setFirstName("xuxu");
        employee.setLastName("zh");
        employee.setAge(26);
        employee.setAbout("i am in peking");
        Employee employee1 = employeeRepository.save(employee);
        System.err.println("add a obj");
        System.out.println(employee1.toString());
        return "success";
    }

    /**
     * 删除
     *
     * @return
     */
    @RequestMapping("delete")
    public String delete() {
        Employee employee = employeeRepository.queryEmployeeById("1");
        employeeRepository.delete(employee);
        return "success";
    }

    /**
     * 局部更新
     *
     * @return
     */
    @RequestMapping("update")
    public String update() {
        Employee employee = employeeRepository.queryEmployeeById("1");
        employee.setFirstName("哈哈");
        employeeRepository.save(employee);
        System.err.println("update a obj");
        return "success";
    }

    /**
     * 查询
     *
     * @return
     */
    @RequestMapping("query")
    public Employee query() {
        Employee accountInfo = employeeRepository.queryEmployeeById("1");
        System.err.println(new Gson().toJson(accountInfo));
        return accountInfo;
    }
    /**
     * ElasticSearch 查询所有
     * */
    @GetMapping(value = "/queryAll")
    public List<Employee> queryAll() {

        List<Employee> list = new ArrayList<>();
        Iterable iterable = (List<Employee>) employeeRepository.findAll();
        Iterator<Employee> iterator = iterable.iterator();
        while (iterator.hasNext()) {
            list.add(iterator.next());
        }
        return list;

    }
    /**
     * ElasticSearch 批量保存
     * */
    @GetMapping(value = "/saveAll")
    public List saveAll() {

        List<Employee> list = new ArrayList<>();
        Employee employee = new Employee();
        employee.setId("20");
        employee.setFirstName("hahahdsfjhjsdkhkfhdsj");
        employee.setLastName("hahahdsfjhjsdkhkfhdsj");
        employee.setAge(26);
        employee.setAbout("hahahdsfjhjsdkhkfhdsj");
        list.add(employee);
        Employee employee2 = new Employee();
        employee2.setId("26");
        employee2.setFirstName("hahahdsfjhjsdkhkfhdsj");
        employee2.setLastName("hahahdsfjhjsdkhkfhdsj");
        employee2.setAge(26);
        employee2.setAbout("hahahdsfjhjsdkhkfhdsj");
        list.add(employee2);
        List<Employee> list1 = (List) employeeRepository.saveAll(list);

        //JDK1.8 Optional
        Optional<Employee> optional = employeeRepository.findById("26");
        System.out.println(optional.map(Employee::getFirstName).map(String::toUpperCase).orElse(null));
        System.out.println(optional);
        System.out.println(optional.isPresent());

        String str = "Hello World";
        Optional<String> notNullOpt = Optional.of(str);
        System.out.println(notNullOpt.isPresent());
        System.out.println(notNullOpt.get());

        String str2 = null;
        Optional<String> nullableOpt = Optional.ofNullable(str2);
        System.out.println(nullableOpt.isPresent());


        Employee employee3 = optional.get();
        System.out.println(employee3);
        System.out.println(String.format("Optional[%s]", "nfsdhfkj"));
        return list1;
    }

    /**
     * 2、查  ++:全文检索（根据整个实体的所有属性，可能结果为0个） 采用queryString 查询
     *
     * @param q
     * @return
     */
    @GetMapping("/select/{q}")
    public List<Employee> testSearch(@PathVariable String q) {
        QueryStringQueryBuilder builder = new QueryStringQueryBuilder(q);
        Iterable<Employee> searchResult = employeeRepository.search(builder);
        Iterator<Employee> iterator = searchResult.iterator();
        List<Employee> list = new ArrayList<Employee>();
        while (iterator.hasNext()) {
            list.add(iterator.next());
        }
        return list;
    }

    /**
     * 3、查   +++：分页、分数、分域（结果一个也不少）
     * @param page
     * @param size
     * @param q
     * @return
     * @return
     */
    @GetMapping("/{page}/{size}/{q}")
    public List<Employee> searchCity(@PathVariable Integer page, @PathVariable Integer size, @PathVariable String q) {


        Pageable pageable = new PageRequest(page, size);

        // 分数，并自动按分排序（对单个属性进行查询）
      /*  FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.
                functionScoreQuery(QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("about", q)),
                        ScoreFunctionBuilders.weightFactorFunction(1000));*/
        // 分数，并自动按分排序（对多个属性进行查询）
        String [] fieldNames =  new String []{"firstName","about","lastName"};

        FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.
                functionScoreQuery(QueryBuilders.boolQuery().should(QueryBuilders.matchQuery(q, fieldNames)),
                        ScoreFunctionBuilders.weightFactorFunction(1000));

        // 分数、分页
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withPageable(pageable)
                .withQuery(functionScoreQueryBuilder).build();

        Page<Employee> searchPageResults = employeeRepository.search(searchQuery);
        return searchPageResults.getContent();

    }
}





